#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "teleinfo.h"

enum Case
{
    insert1 = 1,
    insert2,
    delete,
    search1,
    search2,
    change,
    show,

};

typedef struct TelephoneBook
{
    DArray *array; // 数组指针
    char *name;    // 电话普名字
} Telebook;
typedef struct TelephoneInfo
{
    char *name;
    char *telenumber;
    int numberlen;

} Teleinfo;

void FreeTelebook(void *ptr)
{
    Telebook *b = (Telebook *)ptr;
    FreeDArray(b->array);
    free(b->name);
}
void FreeTeleinfo(void *ptr)
{
    Teleinfo *b = (Teleinfo *)ptr;
    free(b->name);
    free(b->telenumber);
}

Telebook *CreatTelebook(char *name)
{
    Telebook *b = (Telebook *)malloc(sizeof(Telebook));
    if (b == NULL)
    {
        printf("创建失败\n");
        return NULL;
    }
    b->array = InitDArray(10, FreeTeleinfo);
    b->name = strdup(name);

    return b;
}

Teleinfo *CreateInfo(char *name, char *telenumber, int numberlen)
{
    Teleinfo *info = (Teleinfo *)malloc(sizeof(Teleinfo));
    info->name = strdup(name);
    info->numberlen = numberlen;
    info->telenumber = strdup(telenumber);
}

bool IsBookNameWholeEqual(void *ptr1, void *ptr2)
{
    Telebook *b = (Telebook *)ptr1;
    char *name = (char *)ptr2;
    return strcmp(b->name, name) == 0;
}
bool IsInfoNameWholeEqual(void *ptr1, void *ptr2)
{
    Teleinfo *b = (Teleinfo *)ptr1;
    char *name = (char *)ptr2;
    if (strcmp(b->name, name) == 0 || strcmp(b->telenumber, name) == 0)
    {
        return true;
    }
    return false;
}

void InsertInfo2Book(DArray *a, char *telebookname, Teleinfo *s)
{
    Telebook *c = (Telebook *)FindElement(a, telebookname, IsBookNameWholeEqual);
    if (c == NULL)
    {
        printf("没有找到这个电话普:%s\n", telebookname);
        return;
    }
    InsertTail(c->array, s);
}

void PrintTeleinfo(void *ptr)
{
    Teleinfo *b = (Teleinfo *)ptr;
    printf("联系人：%s  电话号码：%s\n", b->name, b->telenumber);
}
void PrintTelebook(void *ptr)
{
    Telebook *b = (Telebook *)ptr;
    printf("电话普名字：%s \n", b->name);
    printf("===================\n");
    PrintArray(b->array, PrintTeleinfo);
}

bool IsInfoNamePartEqual(void *ptr1, void *ptr2)
{
    Teleinfo *b = (Teleinfo *)ptr1;
    char *name = ptr2;
    if (strstr(b->name, name) == NULL && strstr(b->telenumber, name) == NULL)
    {
        return false;
    }
    return true;
}
bool IsBookNamePartEqual(void *ptr1, void *ptr2)
{
    Telebook *b = (Telebook *)ptr1;
    char *name = (char *)ptr2;
    if (strstr(b->name, name) == NULL)
    {
        return false;
    }
    return true;
}

void Delete(DArray *ptr, char *name)
{
    for (int i = 0; i < ReturnSize(ptr); i++)
    {
        Telebook *b = (Telebook *)ReturnArray(ptr, i);
        for (int j = 0; j < ReturnSize(b->array); j++)
        {
            Teleinfo *a = (Teleinfo *)ReturnArray(b->array, j);
            if (a != NULL)
            {
                if (IsInfoNameWholeEqual(a, name) == true)
                {
                    DeleteByElement(b->array, a);
                    j--;
                }
            }
        }
    }
}

void SearchBookPartEqual(DArray *ptr, char *name, bool (*cmp1)(void *, void *), bool (*cmp2)(void *, void *))
{
    Telebook *c = (Telebook *)FindElement(ptr, name, cmp1);
    if (c == NULL)
    {
        bool found = false;
        for (int i = 0; i < ReturnSize(ptr); i++)
        {
            Telebook *b = (Telebook *)ReturnArray(ptr, i);
            for (int j = 0; j < ReturnSize(b->array); j++)
            {
                Teleinfo *a = (Teleinfo *)FindElement(b->array, name, cmp2);
                if (a != NULL)
                {
                    PrintTeleinfo(a);
                    found = true;
                    break;
                }
            }
        }
        if (!found)
        {
            printf(" 没有找到\n");
        }
    }
    else
    {
        printf("%s\n", c->name);
    }
}

void Change(DArray *ptr, char *name1, char *name2)
{

    for (int i = 0; i < ReturnSize(ptr); i++)
    {
        Telebook *b = (Telebook *)ReturnArray(ptr, i);
        for (int j = 0; j < ReturnSize(b->array); j++)
        {
            Teleinfo *a = (Teleinfo *)ReturnArray(b->array, j);
            if (a != NULL)
            {
                if (strcmp(a->name, name1) == 0)
                {
                    a->name = strdup(name2);
                }
                else if (strcmp(a->telenumber, name1) == 0)
                {
                    a->telenumber = strdup(name2);
                }
            }
        }
    }
}

void Search(DArray *ptr, char *name)
{
    for (int i = 0; i < ReturnSize(ptr); i++)
    {
        Telebook *b = (Telebook *)ReturnArray(ptr, i);
        for (int j = 0; j < ReturnSize(b->array); j++)
        {
            Teleinfo *a = (Teleinfo *)ReturnArray(b->array, j);
            if (a != NULL)
            {
                if (strcmp(a->name, name) == 0)
                {
                    PrintTeleinfo(a);
                    return;
                }
                else if (strcmp(a->telenumber, name) == 0)
                {
                    PrintTeleinfo(a);
                    return;
                }
            }
        }
    }
    printf("没找到%s\n", name);
}


int main()
{
    int number;
    DArray *Book = InitDArray(10, FreeDArray);
    InsertTail(Book, CreatTelebook("电话普1"));
    InsertTail(Book, CreatTelebook("电话普2"));

    InsertInfo2Book(Book, "电话普1", CreateInfo("张三", "123", 3));
    InsertInfo2Book(Book, "电话普1", CreateInfo("李四", "456", 3));
    InsertInfo2Book(Book, "电话普2", CreateInfo("王五", "789", 3));
    InsertInfo2Book(Book, "电话普2", CreateInfo("李四", "333", 3));

    while (1)
    {
        printf("请输入想要操作的功能：1.添加电话普  2，添加联系人    3，删除  4，完整查询   5，模糊查询   6，更改联系人或号码  7，显示当前所有.  0,退出 请输入：");
        scanf("%d", &number);
        switch (number)
        {
        case insert1:
            char name[100];
            printf("请输入电话普名字：");
            scanf("%s", name);
            InsertTail(Book, CreatTelebook(name));
            break;
        case insert2:
            char name1[100];
            char telenumber[100];
            char Bookname[100];
            int numberlen;
            printf("请分别输入想插入的电话普名字，联系人名字，联系人电话 ,和电话长度：");
            scanf("%s %s %s %d", Bookname, name1, telenumber, &numberlen);

            InsertInfo2Book(Book, Bookname, CreateInfo(name1, telenumber, numberlen));
            break;
        case delete:
            char name2[100];
            printf("请输入电话或号码删除联系人：");
            scanf("%s", name2);
            Delete(Book, name2);
            break;
        case search1:
            char name3[100];
            printf("输入你想查询的完整电话或名字：");
            scanf("%s", name3);
            Search(Book, name3);
            break;
        case search2:
            char name4[100];
            printf("输入模糊查询的电话普或名字或电话号码：");
            scanf("%s", name4);
            SearchBookPartEqual(Book, name4, IsBookNamePartEqual, IsInfoNamePartEqual);
            break;

        case change:
            char name5[100];
            char name6[100];
            printf("分别输入你想改的名字/号码 和 目标名字/号码：");
            scanf("%s %s", name5, name6);
            Change(Book, name5, name6);
            break;

        case show:
            PrintArray(Book, PrintTelebook);
            break;
        case 0:
            return 0;
            break;
        default:
            printf("错误的选项!\n");
            break;
        }
    }

    return 0;
}